package com.rslai.base.tool.servertest.dsl;

import com.rslai.base.tool.servertest.command.CallStepCommand;
import com.rslai.base.tool.servertest.command.ParameterizedCommand;
import com.rslai.base.tool.servertest.command.StepCommand;
import com.rslai.base.tool.servertest.context.Context;
import com.rslai.base.tool.servertest.model.KeyValueStore;
import com.rslai.base.tool.servertest.model.ServiceDesc;
import com.rslai.base.tool.servertest.reporter.QJSONReporter;
import com.rslai.base.tool.servertest.response.Response;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class DSLCommand extends ParameterizedCommand {
    private static final Set<String> COMMADND_RUNRECORD = new HashSet();
    private DSLCommandDesc desc;
    private List<StepCommand> commands;
    private Map<String, Object> commandParam;
    private StepCommand currentCommand;
    private long startTime;
    public static List<Map<String, Object>> reportList = new ArrayList();

    public void addReportList(Map<String, Object> map) {
        reportList.add(map);
    }

    public void setCurrentCommand(StepCommand currentCommand) {
        this.currentCommand = currentCommand;
    }

    public StepCommand getCurrentCommand() {
        return this.currentCommand;
    }

    public long getStartTime() {
        return this.startTime;
    }

    public DSLCommand(DSLCommandDesc desc, List<KeyValueStore> params, List<StepCommand> commands) {
        super(params);
        this.desc = desc;
        this.commands = commands;
    }

    protected Response doExecuteInternal(Response preResult, List<KeyValueStore> processedParams, Context context) throws Throwable {
        Response response = preResult;
        Boolean run = Boolean.valueOf(COMMADND_RUNRECORD.contains(this.desc.id()));
        if ((this.desc.runOnce().booleanValue()) && (run.booleanValue())) {
            return response;
        }
        COMMADND_RUNRECORD.add(this.desc.id());
        Context childContext = new Context(context);
        Map staticDataMap = (Map) DSLDataProcess.dataMap.get(this.desc.id());
        Map dataMap = this.desc.data();
        for (KeyValueStore processedParam : processedParams) {
            childContext.addContext(processedParam.getName(), processedParam.getValue());
            if ("data".equals(processedParam.getName())) {
                if (dataMap != null) {
                    setCommandParam((Map) dataMap.get(processedParam.getValue()));
                }
                addContext(staticDataMap, processedParam, childContext);
                addContext(dataMap, processedParam, childContext);
            }
        }
        for (StepCommand child : this.commands) {
            if (!(child instanceof DSLCommand)) {
                this.startTime = System.nanoTime();
                if ((child instanceof CallStepCommand)) {
                    CallStepCommand callStepCommand = (CallStepCommand) child;
                    ServiceDesc serviceDesc = (ServiceDesc) QJSONReporter.serviceDescMap.get(callStepCommand.serviceId());
                    if (serviceDesc != null) {
                        serviceDesc.called();
                    }

                    setCurrentCommand(child);
                    response = child.doExecute(response, childContext);

                    long duration = System.nanoTime() - this.startTime;
                    if (serviceDesc != null) {
                        serviceDesc.callSuccess();
                        serviceDesc.addDuration(Long.valueOf(duration));
                    }
                } else {
                    setCurrentCommand(child);
                    response = child.doExecute(response, childContext);
                }

                Map reportMap = child.toReport();
                reportMap.put("duration", Long.valueOf(System.nanoTime() - this.startTime));
                addReportList(reportMap);
            } else {
                setCurrentCommand(child);
                response = child.doExecute(response, childContext);
            }
        }
        return response;
    }

    protected StepCommand doClone() {
        List cloneCommands = new ArrayList();
        for (StepCommand command : this.commands) {
            cloneCommands.add(command.cloneCommand());
        }
        return new DSLCommand(this.desc, this.params, cloneCommands);
    }

    public Map<String, Object> toReport() {
        Map details = new HashMap();
        if (reportList != null) {
            details.put("dslReport", reportList);
            details.put("currentCommand", getCurrentCommand());
        }
        return details;
    }

    private void addContext(Map<String, Map<String, Object>> dataMap, KeyValueStore processedParam, Context childContext) {
        if (dataMap == null) {
            return;
        }
        Map keyValueMap = (Map) dataMap.get(processedParam.getValue());
        Iterator iterator = keyValueMap.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry entry = (Map.Entry) iterator.next();
            childContext.addContext((String) entry.getKey(), entry.getValue());
        }
    }

    public Map<String, Object> getCommandParam() {
        return this.commandParam;
    }

    public void setCommandParam(Map<String, Object> commandParam) {
        this.commandParam = commandParam;
    }

    public DSLCommandDesc getDesc() {
        return this.desc;
    }

    private List<KeyValueStore> convertMapToList(Map<String, Object> map) {
        List keyValueStores = new ArrayList();
        Iterator iterator = map.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry entry = (Map.Entry) iterator.next();
            keyValueStores.add(new KeyValueStore((String) entry.getKey(), entry.getValue()));
        }

        return keyValueStores;
    }
}